﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using MPMovieCatalog.Domain;
using MPMovieCatalog.Service;
using MPMovieCatalog.Forms.Grid;
using MPMovieCatalog.Util;

namespace MPMovieCatalog.Forms
{
    public delegate ArrayList SelectDelegate();

    public delegate long InsertOrUpdateDelegate(ReferenceItem referenceItem);

    public delegate void DeleteDelegate(ArrayList ids);

    public partial class ReferenceForm : Form
    {
        private IMovieService m_movieService = null;

        public ReferenceForm()
        {
            InitializeComponent();

            m_movieService = MovieServiceFactory.getMovieService();

            referenceComboBox.Items.Add(new Reference(ResourceUtils.GetString("lists", 19), m_movieService.FindAllActors, m_movieService.InsertOrUpdateActor, m_movieService.DeleteActors));
            referenceComboBox.Items.Add(new Reference(ResourceUtils.GetString("lists", 20), m_movieService.FindAllGenres, m_movieService.InsertOrUpdateGenre, m_movieService.DeleteGenres));

            UpdateUI();
        }

        private void referenceComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            RefreshBindingSource();
        }

        private void editButton_Click(object sender, EventArgs e)
        {
            EditItem();
        }

        private void addButton_Click(object sender, EventArgs e)
        {
            using (ReferenceEditForm editForm = new ReferenceEditForm())
            {
                editForm.Text = ResourceUtils.GetString("lists", 14);
                if (editForm.ShowDialog(this) == DialogResult.OK)
                {
                    ReferenceItem item = new ReferenceItem();
                    item.Name = editForm.Name;
                    item.Id = ((Reference)referenceComboBox.SelectedItem).InsertOrUpdateDelegate(item);

                    bindingSource.Position = bindingSource.Add(item);
                }
            }
        }


        private void deleteButton_Click(object sender, EventArgs e)
        {
            if (referenceGridView.SelectedRows != null && referenceGridView.SelectedRows.Count > 0)
            {
                if (MessageBox.Show(string.Format(ResourceUtils.GetString("lists", 13), referenceGridView.SelectedRows.Count), ResourceUtils.GetString("common", 1), MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    ArrayList selectedItemsIds = new ArrayList();
                    foreach (DataGridViewRow selectedRow in referenceGridView.SelectedRows)
                    {
                        ReferenceItem selectedItem = (ReferenceItem)selectedRow.DataBoundItem;
                        selectedItemsIds.Add(selectedItem.Id);
                    }

                    ((Reference)referenceComboBox.SelectedItem).DeleteDelegate(selectedItemsIds);
                    RefreshBindingSource();
                }
            }
        }

        private void selectUnusedButton_Click(object sender, EventArgs e)
        {
            foreach (DataGridViewRow row in referenceGridView.Rows)
            {
                ReferenceItem item = (ReferenceItem)row.DataBoundItem;
                row.Selected = item.Used == 0;
            }
        }

        private void refreshButton_Click(object sender, EventArgs e)
        {
            RefreshBindingSource();
        }

        private void referenceGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex >= 0)
            {
                EditItem();
            }
        }

        private void referenceGridView_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.Handled = true;
                EditItem();
            }

        }

        private void referenceGridView_SelectionChanged(object sender, EventArgs e)
        {
            int selectionCount = referenceGridView.SelectedRows.Count;

            editButton.Enabled = selectionCount > 0;
            deleteButton.Enabled = selectionCount > 0;

            editContextMenuItem.Enabled = selectionCount > 0;
            deleteContextMenuItem.Enabled = selectionCount > 0;
        }
        
        private void EditItem()
        {
            using (ReferenceEditForm editForm = new ReferenceEditForm())
            {
                ReferenceItem item = (ReferenceItem)bindingSource.Current;

                editForm.Text = ResourceUtils.GetString("lists", 15);
                editForm.ReferenceItemName = item.Name;

                if (editForm.ShowDialog(this) == DialogResult.OK)
                {
                    item.Name = editForm.ReferenceItemName;
                    ((Reference)referenceComboBox.SelectedItem).InsertOrUpdateDelegate(item);

                    if (bindingSource.IsSorted)
                    {
                        bindingSource.RemoveCurrent();
                        bindingSource.Position = bindingSource.Add(item);

                        bindingSource.Position = bindingSource.IndexOf(item);
                    }
                }
            }
        }
        
        private void RefreshBindingSource()
        {
            Reference reference = referenceComboBox.SelectedItem as Reference;
            bindingSource.DataSource = new SortableBindingList<ReferenceItem>(reference.SelectDelegate());

            addButton.Enabled = true;
            selectUnusedButton.Enabled = true;
            refreshButton.Enabled = true;

            addContextMenuItem.Enabled = true;
        }

        private void UpdateUI()
        {
            this.Text = ResourceUtils.GetString("lists", 0);
            referenceLabel.Text = ResourceUtils.GetString("lists", 1);
            addButton.ToolTipText = ResourceUtils.GetString("lists", 2);
            editButton.ToolTipText = ResourceUtils.GetString("lists", 3);
            deleteButton.ToolTipText = ResourceUtils.GetString("lists", 4);
            selectUnusedButton.ToolTipText = ResourceUtils.GetString("lists", 5);
            refreshButton.ToolTipText = ResourceUtils.GetString("lists", 6);
            nameColumn.HeaderText = ResourceUtils.GetString("lists", 7);
            usedColumn.HeaderText = ResourceUtils.GetString("lists", 8);
            idColumn.HeaderText = ResourceUtils.GetString("lists", 9);
            addContextMenuItem.Text = ResourceUtils.GetString("lists", 10);
            editContextMenuItem.Text = ResourceUtils.GetString("lists", 11);
            deleteContextMenuItem.Text = ResourceUtils.GetString("lists", 12);
        }


        internal class Reference
        {
            public Reference(string name, SelectDelegate selectDelegate, InsertOrUpdateDelegate insertOrUpdateDelegate, DeleteDelegate deleteDelegate)
            {
                Name = name;
                SelectDelegate = selectDelegate;
                InsertOrUpdateDelegate = insertOrUpdateDelegate;
                DeleteDelegate = deleteDelegate;
            }

            public string Name { get; set; }
            public SelectDelegate SelectDelegate { get; set; }
            public InsertOrUpdateDelegate InsertOrUpdateDelegate { get; set; }
            public DeleteDelegate DeleteDelegate { get; set; }

            public override string ToString()
            {
                return Name;
            }
        }
    }
}
